package cn.edu.cug.cs.gtl.apis.ui.catalogtree;

import cn.edu.cug.cs.gtl.apis.ui.AbstractApplication;
import cn.edu.cug.cs.gtl.apis.ui.tree.*;
import cn.edu.cug.cs.gtl.protos.DataCatalog;
import cn.edu.cug.cs.gtl.protos.DataGroup;
import cn.edu.cug.cs.gtl.protos.DataItem;
import cn.edu.cug.cs.gtl.utils.impl.DataItemManagerImpl;
import cn.edu.cug.cs.gtl.utils.postgresql.DataCatalogManager4Postgresql;
import cn.edu.cug.cs.gtl.utils.postgresql.DataGroupManager4Postgresql;

import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeModel;
import java.awt.LayoutManager;
import java.awt.BorderLayout;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

public class CatalogPanel extends TreePanel {
    public CatalogPanel(AbstractApplication theApp, LayoutManager layout, boolean isDoubleBuffered) {
        super(theApp, layout, isDoubleBuffered);
    }

    public CatalogPanel(AbstractApplication theApp, LayoutManager layout) {
        super(theApp, layout);
    }

    public CatalogPanel(AbstractApplication theApp, boolean isDoubleBuffered) {
        super(theApp, isDoubleBuffered);
    }

    public CatalogPanel(AbstractApplication theApp) {
        super(theApp);
    }

    @Override
    public void initial() {
        DataCatalog catalog = new DataCatalogManager4Postgresql().getRoot();

        DefaultMutableTreeNode root = new DefaultMutableTreeNode(new TreeNodeData(catalog, catalog.getAlias(), true), true);

        //用根节点构建一个树模型
        TreeModel treeModel = new DefaultTreeModel(root);

        //用树模型构建一个JTree（如果直接将根节点传递给JTree构造器，那么这棵树就会自动构造一个默认的树模型）
        treeComponent = new CatalogTree(treeModel);
        createTree(treeComponent);

        //设置在JTree中显示的内容为TreeNodeData的text属性而不是整个TreeNodeData对象的toString表示
        //设置节点外观
        final TreeNodeRenderer renderer = new TreeNodeRenderer();
        treeComponent.setCellRenderer(renderer);

        final TreeNodeEditor editor = new TreeNodeEditor(treeComponent);
        treeComponent.setCellEditor(editor);

        //设置树节点可编辑
        treeComponent.setEditable(true);

        treeComponent.addTreeSelectionListener(new CatalogTreeSelectionListener(treeComponent, this.theApp));
        treeModel.addTreeModelListener(new CatalogTreeModelListener(treeComponent, this.theApp));
        treeComponent.addMouseListener(new CatalogTreeMouseListener(treeComponent, this.theApp));

        scrollPane = new JScrollPane(treeComponent);
        add(scrollPane, BorderLayout.CENTER);
    }

    public void createTree(JTree tree) {
        DefaultMutableTreeNode root = (DefaultMutableTreeNode) tree.getModel().getRoot();
        Queue<DefaultMutableTreeNode> queue = new LinkedList<>();
        queue.add(root);
        while (!queue.isEmpty()) {
            DefaultMutableTreeNode parentNode = queue.poll();
            TreeNodeData treeNodeData = (TreeNodeData) parentNode.getUserObject();
            Object object = treeNodeData.getRefObject();
            if (object instanceof DataCatalog) {
                DataCatalog parentCatalog = (DataCatalog) object;
                List<Object> childList = new DataCatalogManager4Postgresql().getChildren(parentCatalog.getName());
                for (Object o : childList) {
                    if (o instanceof DataCatalog) {
                        DataCatalog childCatalog = (DataCatalog) o;
                        DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(
                                new TreeNodeData(childCatalog, childCatalog.getAlias(), true), true);
                        ((DefaultTreeModel) tree.getModel()).insertNodeInto(childNode, parentNode, parentNode.getChildCount());
                        queue.add(childNode);
                    } else expandGroup(tree, parentNode, o);
                }
            } else expandGroup(tree, parentNode, object);
        }
        for (int i = 0; i < tree.getRowCount(); i++) {
            tree.expandPath(tree.getPathForRow(i));
        }
    }

    private void expandGroup(JTree tree, DefaultMutableTreeNode parentNode, Object object) {
        if (object instanceof DataGroup) {
            //将数据组节点添加到树中
            DataGroup childGroup = (DataGroup) object;
            DefaultMutableTreeNode childGroupNode = new DefaultMutableTreeNode(
                    new TreeNodeData(childGroup, childGroup.getAlias(), true), true);
            ((DefaultTreeModel) tree.getModel()).insertNodeInto(childGroupNode, parentNode, parentNode.getChildCount());

            //将数据项节点添加到数据组下
            List<DataItem> childItemList = new DataGroupManager4Postgresql().getDataItemsInGroup(childGroup.getName());
            for (DataItem childItem : childItemList) {
                DefaultMutableTreeNode childItemNode = new DefaultMutableTreeNode(
                        new TreeNodeData(childItem, childItem.getAlias(), true), false);
                ((DefaultTreeModel) tree.getModel()).insertNodeInto(childItemNode, childGroupNode, childGroupNode.getChildCount());
            }
        }
    }

    @Override
    public void reset(Object o) {

    }
}
